//
// Created by bjliuyong on 2021/7/13.
//

#include "ostream.h"



outputStream::outputStream(int width) {
    _width       = width;
    _position    = 0;
    _newlines    = 0;
    _precount    = 0;
    _indentation = 0;
}

stringStream::stringStream(size_t initial_size) : outputStream() {
    buffer_length = initial_size;
    //buffer        = NEW_RESOURCE_ARRAY(char, buffer_length);
    buffer = (char*)malloc(buffer_length);
    buffer_pos    = 0;
    buffer_fixed  = false;
    //DEBUG_ONLY(rm = Thread::current()->current_resource_mark();)
}

void stringStream::write(const char* s, size_t len) {
    size_t write_len = len;               // number of non-null bytes to write
    size_t end = buffer_pos + len + 1;    // position after write and final '\0'
    if (end > buffer_length) {
        if (buffer_fixed) {
            // if buffer cannot resize, silently truncate
            end = buffer_length;
            write_len = end - buffer_pos - 1; // leave room for the final '\0'
        } else {
            // For small overruns, double the buffer.  For larger ones,
            // increase to the requested size.
            if (end < buffer_length * 2) {
                end = buffer_length * 2;
            }
            char* oldbuf = buffer;
            /*
            assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
                   "stringStream is re-allocated with a different ResourceMark");
                   */
            buffer = (char*)malloc(buffer_length);
            strncpy(buffer, oldbuf, buffer_pos);
            buffer_length = end;
            free(oldbuf);
        }
    }
    // invariant: buffer is always null-terminated
    //guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob");
    buffer[buffer_pos + write_len] = 0;
    strncpy(buffer + buffer_pos, s, write_len);
    buffer_pos += write_len;

    // Note that the following does not depend on write_len.
    // This means that position and count get updated
    // even when overflow occurs.
    //update_position(s, len);
}

char* stringStream::as_string() {
    char* copy = (char*)malloc(buffer_pos + 1);
    strncpy(copy, buffer, buffer_pos);
    copy[buffer_pos] = 0;  // terminating null
    return copy;
}

stringStream::~stringStream() {

}

